/*****************************************************************************
*    Copyright (C) 2010 ALi Corp. All Rights Reserved.
*    
*    Company confidential and Properietary information.       
*    This information may not be disclosed to unauthorized  
*    individual.    
*    File: win_otp_bonding_check.c
*   
*    Description: 
*    
*    History: 
*    Date           Athor        Version        Reason
*    ========       ========     ========       ========
*    2010/8/19      tt         
*        
*****************************************************************************/

#include <sys_config.h>
#include <types.h>
#include <osal/osal.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <hld/hld_dev.h>
#include <hld/dmx/dmx_dev.h>
#include <hld/dmx/dmx.h>
#include <hld/decv/vdec_driver.h>
#ifndef NEW_DEMO_FRAME
#include <api/libpub29/lib_hde.h>
#include <api/libpub29/lib_pub27.h>
#else
#include <api/libpub/lib_hde.h>
#endif
#include <api/libosd/osd_lib.h>
#include <bus/otp/otp.h>
	
#include "osdobjs_def.h"
#include "images.id"
#include "string.id"
#include "osd_config.h"
	
#include "menus_root.h"
#include "win_com.h"
#include "control.h"
/*******************************************************************************
*	Objects definition
*******************************************************************************/
#ifndef _CAS9_CA_ENABLE_	
typedef struct
{
	UINT8 dd;
	UINT8 dd_plus;
	UINT8 dolby_pulse;
	UINT8 he_aac;
	UINT8 ms10;
	UINT8 ms11;
	UINT8 mg;
	UINT8 xd;
	UINT8 xd_hd;
	UINT8 usb_num;
	UINT8 ci_num;
	UINT8 mac_num;
	UINT32 reg0;
	UINT32 reg1;
	UINT32 reg2;
	UINT32 reg3;
	UINT32 reg5f;
	UINT8 reg4d_50[16];
	UINT8 reg55_58[16];
	UINT8 reg5d_5e[8];
	UINT8 pd_name[32];
}OTP_BND_FIEAD;

#ifndef SD_UI
#define W_L	140
#define W_T	80
#define W_W	820
#define W_H	460
	
#define TXT_W 	(W_W-60)
#define TXT_H  	44
#define TXT_T 	(W_T + 30)
#define TXT_L 	(W_L + (W_W - TXT_W)/2)
#else
#define W_L	70
#define W_T	40
#define W_W	400
#define W_H	260
	
#define TXT_W 	(W_W-60)
#define TXT_H  	32
#define TXT_T 	(W_T + 20)
#define TXT_L 	(W_L + (W_W - TXT_W)/2)

#endif
	
#define PROG_WIN_SH_IDX         WSTL_POP_WIN_01_8BIT
#define TXT_INFO_IDX            WSTL_TEXT_30_8BIT
	
static VACTION win_otp_check_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT win_otp_check_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

#define LDEF_TXT(root,varTxt,nxtObj,l,t,w,h,align,str)		\
	DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
	0,0,0,0,0, l,t,w,h, TXT_INFO_IDX,TXT_INFO_IDX,TXT_INFO_IDX,TXT_INFO_IDX,   \
	NULL,NULL,	\
	(align)|C_ALIGN_VCENTER, 0,0,0,str)

#define LDEF_WIN(varWnd,nxtObj,l,t,w,h,sh,nextObj,focusID)		\
	DEF_CONTAINER(varWnd,NULL,NULL,C_ATTR_ACTIVE,0, \
		0,0,0,0,0, l,t,w,h, sh,sh,sh,sh,   \
		win_otp_check_keymap,win_otp_check_callback,	\
		nextObj, focusID,1)

extern CONTAINER  g_win_otp_check;
extern TEXT_FIELD txt_otp_check_title;
extern TEXT_FIELD txt_otp_pd_name;
extern TEXT_FIELD txt_otp_feature;
extern TEXT_FIELD txt_otp_fbonding;
extern TEXT_FIELD txt_otp_xd;
extern TEXT_FIELD txt_otp_reg02;
extern TEXT_FIELD txt_otp_reg03;
extern TEXT_FIELD txt_otp_reg5f;
extern TEXT_FIELD txt_otp_chipid;

LDEF_TXT(&g_win_otp_check,txt_otp_check_title,&txt_otp_pd_name, TXT_L,(TXT_T + TXT_H * 0),TXT_W,TXT_H,C_ALIGN_CENTER,display_strs[0])
LDEF_TXT(&g_win_otp_check,txt_otp_pd_name,    &txt_otp_feature, TXT_L,(TXT_T + TXT_H * 1),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[1])
LDEF_TXT(&g_win_otp_check,txt_otp_feature,    &txt_otp_xd,    TXT_L,(TXT_T + TXT_H * 2),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[2])
LDEF_TXT(&g_win_otp_check,txt_otp_xd,       &txt_otp_fbonding,TXT_L,(TXT_T + TXT_H * 3),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[3])
LDEF_TXT(&g_win_otp_check,txt_otp_fbonding,   &txt_otp_reg02,	TXT_L,(TXT_T + TXT_H * 4),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[4])
LDEF_TXT(&g_win_otp_check,txt_otp_reg02,      &txt_otp_reg03,   TXT_L,(TXT_T + TXT_H * 5),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[5])
LDEF_TXT(&g_win_otp_check,txt_otp_reg03,      &txt_otp_reg5f,   TXT_L,(TXT_T + TXT_H * 6),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[6])
LDEF_TXT(&g_win_otp_check,txt_otp_reg5f,      &txt_otp_chipid,  TXT_L,(TXT_T + TXT_H * 7),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[7])
LDEF_TXT(&g_win_otp_check,txt_otp_chipid,	  NULL, 			TXT_L,(TXT_T + TXT_H * 8),TXT_W,TXT_H,C_ALIGN_LEFT,display_strs[8])

LDEF_WIN(g_win_otp_check,NULL,W_L,W_T,W_W,W_H,PROG_WIN_SH_IDX,&txt_otp_check_title,1);

static TEXT_FIELD *txt_array[] = 
{
	&txt_otp_check_title,
	&txt_otp_pd_name,
	&txt_otp_feature,
	&txt_otp_xd,
	&txt_otp_fbonding,
	&txt_otp_reg02,
	&txt_otp_reg03,
	&txt_otp_reg5f,	
	&txt_otp_chipid,
};

static OTP_BND_FIEAD m_otp_bnd;

typedef struct
{
	UINT8 pd_name[16];
	UINT8 usb_num;
	UINT8 ci_slot_num;
}PRODUCT_BND;

static PRODUCT_BND m_product_bnd[] = 
{
	{"M3601E", 1, 0},
	{"M3381E", 1, 0},
	{"M3606", 2, 0},
	{"M3606B", 1, 0},
	{"M3606C", 2, 1},
	{"M3606D", 1, 1},
	{"M3386", 2, 0},
	{"M3386B", 1, 0},
	{"M3386C", 2, 1},
	{"M3386D", 1, 1},
	{"M3701C", 2, 0},
	{"M3701D", 1, 0},
	{"M3701E", 2, 0},
	{"M3701F", 1, 0},
	{"M3603", 2, 2},
	{"M3383", 2, 2},
	{"M3601S", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
	{"Error", 1, 0},
};

static UINT8 product_sub_name[][16] = 
{
	"-ALxA",
	"-APxA",
};

static UINT32 feature_idx2bnd[] = 
{	
//  A     B    C    D    E    F    G    H    I    J    K    L    M    N
	0x00,0x01,0x03,0x07,0x0f,0x10,0x11,0x13,0x17,0x1f,0x31,0x71,0x30,0x70,0,	
};

static void otp_info_load(void)
{
	UINT32 i;
	UINT8 disp_str[100];
	UINT32 temp;
	UINT32 product_index;
	PTEXT_FIELD txt_ptr;
	UINT8 feature_bnd;
	UINT32 bit_bnd;

	MEMSET(&m_otp_bnd, 0, sizeof(m_otp_bnd));			

	//load otp value
	otp_init(NULL);

#if 1
	otp_read(0, &m_otp_bnd.reg0, 4);
	otp_read(1*4, &m_otp_bnd.reg1, 4);
	otp_read(2*4, &m_otp_bnd.reg2, 4);
	otp_read(3*4, &m_otp_bnd.reg3, 4);
	otp_read(0x5f*4, &m_otp_bnd.reg5f, 4);
	otp_read(0x4d*4, m_otp_bnd.reg4d_50, 16);
	otp_read(0x55*4, m_otp_bnd.reg55_58, 16);
	otp_read(0x5d*4, m_otp_bnd.reg5d_5e, 8);
#else	
	m_otp_bnd.reg2 = 0x12344278;
	m_otp_bnd.reg3 = 0x12345678;
	m_otp_bnd.reg5f = 0x12345678;
#endif	
	libc_printf("m_otp_bnd.reg2 = %xh\n", m_otp_bnd.reg2);
	libc_printf("m_otp_bnd.reg3 = %xh\n", m_otp_bnd.reg3);
	libc_printf("m_otp_bnd.reg5f = %xh\n", m_otp_bnd.reg5f);

    libc_printf("m_otp_bnd.reg4d_50 = ");
    for (i = 0; i < 16; i++) 
	    libc_printf("%02x,", m_otp_bnd.reg4d_50[i]);
    libc_printf("\n");

    libc_printf("m_otp_bnd.reg55_58 = ");
    for (i = 0; i < 16; i++) 
	    libc_printf("%02x,", m_otp_bnd.reg55_58[i]);
    libc_printf("\n");

    libc_printf("m_otp_bnd.reg5d_5e = ");
    for (i = 0; i < 8; i++) 
	    libc_printf("%02x,", m_otp_bnd.reg5d_5e[i]);
    libc_printf("\n");


	//get product name
	product_index = (m_otp_bnd.reg2>>20)&0x1f;
	feature_bnd = (m_otp_bnd.reg2>>6)&0x7f;

	if(feature_bnd == 0x7f)
	{
		//"Z", Ali test Chip, full function
		feature_bnd = 0x19;
	}
	
	strcat(m_otp_bnd.pd_name, m_product_bnd[product_index].pd_name);
	
	if(product_index<0x0e)
	{
		product_sub_name[0][3] = 'A' + feature_bnd; 
		strcat(m_otp_bnd.pd_name, product_sub_name[0]);
	}
	else
	{
		product_sub_name[1][3] = 'A' + feature_bnd;
		strcat(m_otp_bnd.pd_name, product_sub_name[1]);
	}

	//get bonding
	if(feature_bnd == 0x19) //"Z", Ali test Chip, full function
		bit_bnd = 0xff;
	else if(feature_bnd > 13)
		bit_bnd = 0;
	else	
		bit_bnd = feature_idx2bnd[feature_bnd];

	if(bit_bnd&0x01)
		m_otp_bnd.dd = 1;
	if(bit_bnd&0x02)
		m_otp_bnd.dd_plus = 1;
	if(bit_bnd&0x04)
		m_otp_bnd.ms10 = 1;
	if(bit_bnd&0x08)
		m_otp_bnd.ms11 = 1;
	if(bit_bnd&0x10)
		m_otp_bnd.mg = 1;
	if(bit_bnd&0x20)
		m_otp_bnd.xd = 1;
	if(bit_bnd&0x40)
		m_otp_bnd.xd_hd = 1;

	m_otp_bnd.usb_num = m_product_bnd[product_index].usb_num;
	m_otp_bnd.ci_num = m_product_bnd[product_index].ci_slot_num;
    m_otp_bnd.mac_num = sys_ic_get_mac_num();

	//display
	for(i = 0; i< ARRAY_SIZE(txt_array); i++)
	{
		txt_ptr = txt_array[i];
	
		if(i == 0)
		{
			sprintf(disp_str,"OTP Configuration");
		}
		else if(i == 1)
		{
			//product name: reg02, bit24-bit20
			temp = (m_otp_bnd.reg2>>20)&0x1f;
			sprintf(disp_str,"Product Name: bit[24-20]=[%05b]  --  %s",temp,m_otp_bnd.pd_name);
		}
		else if(i == 2)
		{
			//feature config: reg02, bit12-bit6
			temp = (m_otp_bnd.reg2>>6)&0x7f;
			sprintf(disp_str,"Feature Cfg: bit[12-6]=[%07b]",temp);
		}
		else if(i == 3)
		{
			//xd: reg03, bit31-bit30
			temp = (m_otp_bnd.reg3>>30)&0x3;
			sprintf(disp_str,"xd Cfg: bit[31-30]=[%02b]",temp);
		}
		else if(i == 4)
		{
			MEMSET(disp_str, 0, sizeof(disp_str));
			if(m_otp_bnd.dd)
				strcat(disp_str, "DD/");
			if(m_otp_bnd.dd_plus)
				strcat(disp_str, "DD+/");
			if(m_otp_bnd.dolby_pulse)
				strcat(disp_str, "DDP/");
			if(m_otp_bnd.he_aac)
				strcat(disp_str, "AAC/");
			if(m_otp_bnd.ms10)
				strcat(disp_str, "MS10/");
			if(m_otp_bnd.ms11)
				strcat(disp_str, "MS11/");
			if(m_otp_bnd.mg)
				strcat(disp_str, "MG/");
			if(m_otp_bnd.xd)
				strcat(disp_str, "xd/");
			if(m_otp_bnd.xd_hd)
				strcat(disp_str, "xdHD/");
			if(m_otp_bnd.usb_num == 2)
				strcat(disp_str, "USB*2/");
			else if(m_otp_bnd.usb_num == 1)
				strcat(disp_str, "USB*1/");

			if(m_otp_bnd.ci_num == 2)
				strcat(disp_str, "CI*2");
			else if(m_otp_bnd.ci_num == 1)
				strcat(disp_str, "CI*1");			
			else
				strcat(disp_str, "CI*0");

			if(m_otp_bnd.mac_num == 1)
				strcat(disp_str, "/MAC*1");
			else
				strcat(disp_str, "/MAC*0");
		}
		else if(i == 5)
		{
			//reg02
			sprintf(disp_str,"Reg0x02: bit[31-0]=[0x%xh]",m_otp_bnd.reg2);
		}
		else if(i == 6)
		{
			//reg03
			sprintf(disp_str,"Reg0x03: bit[31-0]=[0x%xh]",m_otp_bnd.reg3);
		}
		else if(i == 7)
		{
			//reg5f
			sprintf(disp_str,"Reg0x5f: bit[31-0]=[0x%xh]",m_otp_bnd.reg5f);
		}
		else if( i == 8)
		{
			// chip id
			sprintf(disp_str,"Chip ID = 0x%x%08xh", m_otp_bnd.reg1&0xffff, m_otp_bnd.reg0);
		}
	
		libc_printf("otp: %d, %s\n", i, disp_str);
		OSD_SetTextFieldContent(txt_ptr, STRING_ANSI, (UINT32)disp_str);
	}
	
}


/*******************************************************************************
*	function definition
*******************************************************************************/
static VACTION win_otp_check_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	
	switch(key)
	{
	case V_KEY_MENU:
	case V_KEY_INFOR:
	case V_KEY_EXIT:
		act = VACT_CLOSE;
		break;			
	default:	
		act = VACT_PASS;
		break;
	}
	
	return act;
}

static PRESULT win_otp_check_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{	
	PRESULT ret = PROC_PASS;
	UINT32	vkey;
	POBJECT_HEAD topmenu;

	switch(event)
	{
	case EVN_PRE_OPEN:
		//api_inc_wnd_count();
		otp_info_load();
		wincom_close_title();
		if(menu_stack_get(0) == (POBJECT_HEAD)&g_win_mainmenu)
		{
			OSD_ClearObject( (POBJECT_HEAD) &g_win_mainmenu, C_UPDATE_ALL);
			topmenu = menu_stack_get_top();
			if(topmenu)
				OSD_ClearObject( topmenu, C_UPDATE_ALL);
		}
		
		break;
	case EVN_POST_OPEN:
		break;
	case EVN_MSG_GOT:
		break;
	case EVN_PRE_CLOSE:
		break;
	case EVN_POST_CLOSE:
		//api_dec_wnd_count();
		if(menu_stack_get(0) == (POBJECT_HEAD)&g_win_mainmenu)
			OSD_TrackObject( (POBJECT_HEAD) &g_win_mainmenu, C_UPDATE_ALL);	
		
		break;

	case EVN_UNKNOWNKEY_GOT:
		break;
	default:
		break;
	}

	return ret;
}
#endif

